#!/usr/bin/env bash

# 有命令出错的时候就退出
set -e

# 判定环境变量是否已经被设置
if [[ -z $NDK_ROOT ]]; then
    echo "需要指定 NDK_ROOT 环境变量，指出 android NDK 的根路径"
    exit 1
fi

if [[ -z $ANDROID_API ]]; then
    echo "需要指定 ANDROID_API 环境变量，指出要使用的 android API 的版本"
    exit 1
fi

# 判定参数
if [[ $# -lt 1 ]]; then
    echo "需要传递一个要构建的目标 ABI 参数。可用值为：armeabi-v7a | arm64-v8a"
    exit 1
fi

# 判定参数是否有效
case $1 in
    armeabi-v7a )
        ANDROID_TARGET=armv7a-linux-androideabi
        ANDROID_TARGET_ARCH=arm-linux-androideabi
        ;;
    arm64-v8a )
        ANDROID_TARGET=aarch64-linux-android
        ANDROID_TARGET_ARCH=$ANDROID_TARGET
        ;;
    *)
        echo "参数无效。可用参数为：armeabi-v7a | arm64-v8a"
        exit 1
        ;;
esac

function yellow_print() {
    echo -e "\033[33m${1}\033[0m"
}

# 载入配置
CURDIR=$(cd `dirname $0`;pwd)
BUILDDIR=$CURDIR/build
ARCH=$1
ARCHDIR=$BUILDDIR/$ARCH
PREFIX=$ARCHDIR/output
NDK_TOOLCHAIN=${NDK_ROOT}/toolchains/llvm/prebuilt/darwin-x86_64
PKG_CONFIG_PATH=${PREFIX}/lib/pkgconfig
PKG_CONFIG_LIBDIR=${PKG_CONFIG_PATH}
# 确定并行构建的线程数量
CORES=`sysctl -n hw.ncpu`
BUILD_THREADS=$(expr $CORES / 2 + $CORES)

export PATH=$PATH:${PREFIX}/bin:${PREFIX}/lib:${PREFIX}/include:${NDK_TOOLCHAIN}/bin
export CC=${ANDROID_TARGET}${ANDROID_API}-clang
export CXX=${ANDROID_TARGET}${ANDROID_API}-clang++
export AR=${ANDROID_TARGET_ARCH}-ar
export AS=${CC}
export LD=${ANDROID_TARGET_ARCH}-ld
export STRIP=${ANDROID_TARGET_ARCH}-strip
export CFLAGS="-fPIE -fPIC -I${PREFIX}/include --sysroot=${NDK_TOOLCHAIN}/sysroot -I${NDK_TOOLCHAIN}/sysroot/include -Werror=implicit-function-declaration -fno-integrated-as"
export CXXFLAGS=${CFLAGS}
export CPPFLAGS=${CFLAGS}
export LDFLAGS="-pie -Wl,-rpath-link=-I${NDK_TOOLCHAIN}/sysroot/usr/lib -L${NDK_TOOLCHAIN}/sysroot/usr/lib -L${PREFIX}/lib -L${NDK_TOOLCHAIN}/lib"

. $CURDIR/config.sh
mkdir -p $PREFIX

function extract_file() {
    # $1 待解压文件
    # $2 目标路径
    subfix=${1##*.}
    ep=''
    if [[ $subfix == 'gz' ]]; then
        ep='z'
    elif [[ $subfix == 'xz' ]]; then
        ep='J'
    elif [[ $subfix == 'bz2' ]]; then
        ep='j'
    fi
    ep=-x${ep}f

    dst=$ARCHDIR/$2
    if [[ -d $dst ]]; then
        rm -rf $dst
    fi

    tar $ep $1 -C $ARCHDIR
    pushd $dst
}

# 开始构建

# libiconv
function build_iconv() {
    yellow_print "开始构建 libiconv"
    extract_file $ICONV_FILE $ICONV_EX_DIR
    ./configure --host=${ANDROID_TARGET_ARCH} --prefix=${PREFIX} --disable-rpath --disable-static
    make -j ${BUILD_THREADS}
    make install
    popd
}

# libffi
function build_ffi() {
    yellow_print "开始构建 libffi"
    extract_file $FFI_FILE $FFI_EX_DIR
    sed -e '/^includesdir/ s/$(libdir).*$/$(includedir)/' -i "" include/Makefile.in
    sed -e '/^includedir/ s/=.*$/=@includedir@/' -e 's/^Cflags: -I${includedir}/Cflags:/' -i "" libffi.pc.in
    ./configure --prefix=${PREFIX} --disable-static --host=${ANDROID_TARGET_ARCH}
    make -j ${BUILD_THREADS}
    make install
    popd
}

# gettext
function build_gettext() {
    yellow_print "开始构建 gettext"
    extract_file $GETTEXT_FILE $GETTEXT_EX_DIR
    ./configure  --prefix=${PREFIX} --disable-rpath --disable-libasprintf --disable-java --disable-native-java --disable-openmp --disable-curses --host=${ANDROID_TARGET_ARCH} --disable-static
    make -j ${BUILD_THREADS}
    # 这里会出错，但是不要紧。直接忽略
    $(make install 2>&1 > /dev/null) || true
    popd
}

# glib
function build_glib() {
    yellow_print "开始构建 glib"
    extract_file $GLIB_FILE $GLIB_EX_DIR
cat << EOF > android.cache
glib_cv_long_long_format=ll
glib_cv_stack_grows=no
glib_cv_sane_realloc=yes
glib_cv_va_val_copy=yes
glib_cv_have_strlcpy=no
glib_cv_rtldglobal_broken=no
glib_cv_uscore=no
glib_cv_monotonic_clock=no
ac_cv_func_nonposix_getpwuid_r=no
ac_cv_func_posix_getpwuid_r=no
ac_cv_func_posix_getgrgid_r=no
glib_cv_use_pid_surrogate=yes
ac_cv_func_printf_unix98=no
ac_cv_func_vsnprintf_c99=yes
ac_cv_func_realloc_0_nonnull=yes
ac_cv_func_realloc_works=yes
EOF

    chmod a-x android.cache
    NOCONFIGURE=true ./autogen.sh
    ./configure --prefix=${PREFIX} --disable-dependency-tracking --cache-file=android.cache --enable-included-printf --disable-static --with-pcre=no --enable-libmount=no --with-libiconv=gnu --host=${ANDROID_TARGET_ARCH}
    make -j ${BUILD_THREADS}
    make install
    popd
}

# oboe
function build_oboe() {
    yellow_print "开始构建 oboe"
    extract_file $OBOE_FILE $OBOE_EX_DIR
    mkdir -p build
    pushd build
    cmake -G "Unix Makefiles" -DCMAKE_MAKE_PROGRAM=make \
        -DCMAKE_TOOLCHAIN_FILE=${NDK_ROOT}/build/cmake/android.toolchain.cmake \
        -DANDROID_NATIVE_API_LEVEL=${ANDROID_API} \
        -DANDROID_ABI=${ARCH} \
        -DANDROID_PLATFORM=android-${ANDROID_API} \
        -DBUILD_SHARED_LIBS=0 .. \
        -DCMAKE_VERBOSE_MAKEFILE=1
    make -j ${BUILD_THREADS}
    cp liboboe.a* ${PREFIX}/lib/
    cp -r ../include/oboe ${PREFIX}/include
cat << EOF > ${PKG_CONFIG_PATH}/oboe-1.0.pc
prefix=${PREFIX}
exec_prefix=\${prefix}
libdir=\${prefix}/lib
includedir=\${prefix}/include

Name: Oboe
Description: Oboe library
Version: ${OBOE_VER}
Libs: -L\${libdir} -loboe -landroid -llog -lstdc++
Cflags: -I\${includedir}
EOF

    popd
    popd
}

### fluidsynth
function build_fluidsynth() {
    yellow_print "开始构建 fluidsynth"
    extract_file $FLUIDSYNTH_FILE $FLUIDSYNTH_EX_DIR
    # 用我修改过的，处理了 stream 重连的
    cp $CURDIR/fluid_oboe.cpp src/drivers/fluid_oboe.cpp
    mkdir -p build
    pushd build
    cmake -G "Unix Makefiles" -DCMAKE_MAKE_PROGRAM=make \
        -DCMAKE_TOOLCHAIN_FILE=${NDK_ROOT}/build/cmake/android.toolchain.cmake \
        -DANDROID_NATIVE_API_LEVEL=${ANDROID_API} \
        -DANDROID_ABI=${ARCH} \
        -DANDROID_TOOLCHAIN=clang \
        -DANDROID_NDK=${NDK_ROOT} \
        -DCMAKE_INSTALL_PREFIX=${PREFIX} \
        -DCMAKE_VERBOSE_MAKEFILE=1 \
        -DCMAKE_PREFIX_PATH=${PREFIX} \
        -Denable-libsndfile=0 \
        -Denable-opensles=1 \
        -Denable-sdl2=0 \
        -Denable-oboe=1 \
        -Denable-dbus=0 \
        -Denable-oss=0 ..
    make -j ${BUILD_THREADS}
    make install
    popd
    popd
}

# 输出发布用的动态库
function do_release() {
    yellow_print "执行发布"
    RELEASE_DIR=$ARCHDIR/release
    mkdir -p $RELEASE_DIR
    for f in ffi glib-2.0 gobject-2.0 iconv fluidsynth gmodule-2.0 gthread-2.0 intl;do
        src=$PREFIX/lib/lib${f}.so
        dst=$RELEASE_DIR/lib${f}.so
        if [[ -f $src ]]; then
            cp $src $dst
        fi
    done
    ## 64 位的 fluidsynth 构建在 lib64 目录
    if [[ -d $PREFIX/lib64 ]];then
        cp $PREFIX/lib64/*.so $RELEASE_DIR/
    fi
    ## 执行strip
    $STRIP $RELEASE_DIR/*.so
    chmod -x $RELEASE_DIR/*.so

    echo -e "\033[32m成功发布在目录 \033[0m$RELEASE_DIR"
}

build_iconv
build_ffi
build_gettext
build_glib
build_oboe
build_fluidsynth
do_release
